<template>
  <div id="app-page">
    <!-- 地图区域 -->
    <div class="methane-monitor-overlay" v-if="methaneVisible && methaneMonitorConfig.url && methaneMonitorConfig.url !== 'undefined'">
      <MethaneMonitor
        :mqtt-url="methaneMonitorConfig.url"
        :topic="methaneMonitorConfig.topic"
      />
    </div>
    <div class="map-toolbar">
      <button
        v-for="tool in mapTools"
        :key="tool.id"
        class="tool-btn"
        :class="{ active: activeTool === tool.id }"
        @click.stop="handleToolClick(tool.id)"
      >
        <el-tooltip
          class="item"
          effect="dark"
          :content="tool.label"
          placement="right"
        >
          <span class="tool-icon"><i :class="tool.icon"></i></span>
        </el-tooltip>
      </button>
      <div class="tool-divider"></div>
      <button class="tool-btn secondary" @click.stop="handleToolCenter">
        <el-tooltip
          class="item"
          effect="dark"
          content="返回当前位置"
          placement="right"
        >
          <span class="tool-icon"
            ><i class="iconfont icon-dangqianweizhi"></i
          ></span>
        </el-tooltip>
      </button>
    </div>
    <div class="map-warp" id="map"></div>
    <transition name="route-panel">
      <RouteToolPanel
        v-if="routePanelVisible"
        :route-form="routeForm"
        :route-drawing-active="routeDrawingActive"
        :route-editing-index="routeEditingIndex"
        @close="resetActiveTool"
        @start-drawing="startRouteDrawing"
        @clear="clearRoutePlanning"
        @focus-waypoint="focusWaypoint"
        @remove-waypoint="removeWaypoint"
        @update-waypoint-field="onRouteWaypointFieldUpdate"
        @update-field="onRouteFieldUpdate"
        @download="downloadRouteKml"
        @submit="submitRoutePlan"
        @load-route="openRouteSelector"
        @route-updated="handleRouteUpdated"
      />
      <FenceToolPanel
        v-else-if="fencePanelVisible"
        :fence-form="fenceForm"
        :fence-drawing-active="fenceDrawingActive"
        :fence-editing-index="fenceEditingIndex"
        @close="resetActiveTool"
        @start-drawing="startFenceDrawing"
        @clear="clearFencePlanning"
        @focus-point="focusFencePoint"
        @remove-point="removeFencePoint"
        @update-point-field="onFencePointFieldUpdate"
        @update-field="onFenceFieldUpdate"
        @change-type="handleFenceTypeChange"
        @submit="submitFencePlan"
      />
    </transition>
    <!-- 地址查询（仅测量页面显示） -->
    <div class="map-search" v-if="searchVisible">
      <input
        v-model="searchKeyword"
        class="search-input"
        type="text"
        placeholder="搜索地址/地名，例如：西安市高新区"
        @keyup.enter="handleSearch"
      />
      <button
        class="search-btn"
        :disabled="searchLoading"
        @click="handleSearch"
      >
        {{ searchLoading ? "查询中..." : "搜索" }}
      </button>
      <ul v-if="searchResults.length" class="search-results">
        <li
          v-for="(item, idx) in searchResults"
          :key="idx"
          @click="selectResult(item)"
        >
          <span class="name">{{ item.name }}</span>
        </li>
      </ul>
      <div v-if="searchError" class="search-error">{{ searchError }}</div>
    </div>

    <flightAlert :show="showNoFlyAlert" @close="showNoFlyAlert = false" />

    <!-- 航线选择面板 -->
    <transition name="fade">
      <div v-if="routeSelectorVisible" class="route-selector-panel">
        <div class="route-selector-header">
          <h3>选择航线</h3>
          <div class="route-selector-actions">
            <el-button
              class="route-selector-confirm"
              size="small"
              type="primary"
              style="margin-right: 10px"
              @click.stop="confirmRouteSelection"
              >确定</el-button
            >
            <button
              class="route-selector-close"
              @click.stop="routeSelectorVisible = false"
            >
              ✖
            </button>
          </div>
        </div>
        <div class="route-selector-body">
          <div class="route-selector-search">
            <input
              type="text"
              placeholder="搜索航线名称..."
              v-model="routeSearchQuery"
              @input="filterRoutes"
            />
          </div>
          <div class="route-selector-list">
            <div
              v-for="route in filteredRoutes"
              :key="route.id"
              class="route-selector-item"
              :class="{
                selected: selectedRoutes.some((r) => r.id === route.id),
              }"
              @click.stop="toggleRouteSelection(route)"
            >
              <div class="route-selector-content">
                <span class="route-name">{{ route.name }}</span>
                <span class="route-info"
                  >航点: {{ route.waypoint_count || route.waypoints.length }} |
                  距离: {{ route.distance || 0 }}m</span
                >
              </div>
              <div class="route-selector-checkbox">
                <span
                  v-if="selectedRoutes.some((r) => r.id === route.id)"
                  class="checkbox-checked"
                  >✓</span
                >
              </div>
            </div>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup>
import {
  computed,
  defineEmits,
  defineExpose,
  nextTick,
  onBeforeUnmount,
  onMounted,
  provide,
  reactive,
  shallowRef,
  watch,
  ref,
} from "vue";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "@geoman-io/leaflet-geoman-free";
import "@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
import "leaflet-measure-path/leaflet-measure-path.css";
import "leaflet-measure-path/leaflet-measure-path.js";
import { useRoute, onBeforeRouteLeave } from "vue-router";
import flightAlert from "./flightAlert.vue";
import RouteToolPanel from "./RouteToolPanel.vue";
import FenceToolPanel from "./FenceToolPanel.vue";
import MethaneMonitor from "@/components/MethaneMonitor.vue";
import { ElMessage } from "element-plus";
import { downloadKml } from "@/utils/downloadKml";
import { noFlyZoneService, flightRouteService } from "@/api";
const route = useRoute();

// 路由离开前清理地图资源
onBeforeRouteLeave(() => {
  // 清除定时器
  if (zoomRenderTimer) clearTimeout(zoomRenderTimer);
  if (moveRenderTimer) clearTimeout(moveRenderTimer);

  // 清理所有地图资源，与onBeforeUnmount保持一致
  resetRouteEditing();
  resetFenceEditing();
  clearDisplayedRoute();

  if (mapRef.value) {
    // 移除所有标记
    clearActiveTaskLayers();
    clearPointMarkers(mapRef.value);

    // 移除所有事件监听器
    mapRef.value.off("pm:create", handleDrawCreate);
    mapRef.value.off("pm:drawend", handleDrawEnd);
    mapRef.value.off("moveend", handleBoundsChange);
    mapRef.value.off("zoomend");
    mapRef.value.off("moveend");

    // 移除特殊图层
    try {
      if (noFlyLayer) mapRef.value.removeLayer(noFlyLayer);
    } catch (e) {}

    // 最后移除地图实例
    mapRef.value.remove();
  }

  // 清空引用
  mapRef.value = null;
});
const emit = defineEmits(["drone-click", "tool-click"]);
const showNoFlyAlert = ref(false); //禁飞区警告
const mapRef = shallowRef(null);
provide("leafletMap", mapRef);
const pointMarkers = [];
const defaultPointHeight = "默认高度：100m";
let activeTaskRoute = null;
const taskWaypointMarkers = [];
let activeDroneMarker = null;
let activeDroneId = null;
let dronePopup = null;
const activeTool = ref(null);
const routes = ref([]);
const selectedRoute = ref(null);
const selectedRoutes = ref([]); // 存储多个选中的航线
const routeSelectorVisible = ref(false);
const routeSearchQuery = ref("");
const filteredRoutes = ref([]);
const displayedRoutes = ref([]); // 存储显示的航线图层信息
const mapTools = [
  { id: "figure", label: "实时统计", icon: "iconfont icon-tongji" },
  {
    id: "taskmonitor",
    label: "监控驾驶舱",
    icon: "iconfont icon-jiankongzhongxin",
  },
  { id: "measure", label: "测距工具", icon: "iconfont icon--_juliceliang" },
  { id: "route", label: "航路航线", icon: "iconfont icon-juli-copy" },
  { id: "fence", label: "电子围栏", icon: "iconfont icon-weilanguanli" },
];
const routeForm = reactive({
  name: "",
  description: "",
  duration: "",
  waypoints: [],
  defaultAltitude: 120,
  defaultSpeed: 12,
});
const fenceForm = reactive({
  name: "",
  description: "",
  type: "polygon",
  altitude: 120,
  active: true,
  centerLat: "34.24567",
  centerLng: "108.906253",
  radius: 200,
  points: [],
});
const routeDrawingActive = ref(false);
const searchVisible = computed(() =>
  ["measure", "route", "fence"].some((r) => r == activeTool.value)
);
const methaneVisible = computed(
  () => activeTool.value === "taskmonitor" || activeDroneMarker
);
const routePanelVisible = computed(() => activeTool.value === "route");
const fencePanelVisible = computed(() => activeTool.value === "fence");
const routeLayerRef = shallowRef(null);
const routeMarkerRefs = [];
const fenceMarkerRefs = [];
const fenceLayerRef = shallowRef(null);
const fenceDrawingActive = ref(false);
const fenceEditingIndex = ref(null);
const routeEditingIndex = ref(null);
const methaneMonitorConfig = {
  url: import.meta.env.VITE_METHANE_MQTT_URL || undefined,
  topic: import.meta.env.VITE_METHANE_MQTT_TOPIC || 'sensors/methane',
};
const TIANDITU_API_KEY = "b96f5225ccf95b9dff787409324753ce";
const TOOL_CONFIG = {
  measure: {
    type: "Line",
    options: {
      allowSelfIntersection: false,
      templineStyle: { color: "#2f88ff" },
      pathOptions: { color: "#2f88ff", weight: 3 },
    },
  },
  route: {
    type: "Line",
    options: {
      allowSelfIntersection: false,
      templineStyle: { color: "#ff7a45" },
      pathOptions: { color: "#ff7a45", weight: 3 },
    },
    flight: true,
  },
  fence: {
    type: "Polygon",
    options: {
      allowSelfIntersection: false,
      pathOptions: {
        color: "#52c41a",
        weight: 2,
        fillColor: "#52c41a",
        fillOpacity: 0.12,
      },
    },
  },
};

const clearActiveTaskLayers = () => {
  const map = mapRef.value;
  if (!map) return;
  if (activeTaskRoute) {
    try {
      map.removeLayer(activeTaskRoute);
    } catch (e) {}
    activeTaskRoute = null;
  }
  while (taskWaypointMarkers.length) {
    const marker = taskWaypointMarkers.pop();
    try {
      map.removeLayer(marker);
    } catch (e) {}
  }
  if (activeDroneMarker) {
    if (activeDroneMarker.__clickHandler) {
      activeDroneMarker.off("click", activeDroneMarker.__clickHandler);
    }
    try {
      map.removeLayer(activeDroneMarker);
    } catch (e) {}
    activeDroneMarker = null;
  }
  if (dronePopup) {
    try {
      map.closePopup(dronePopup);
    } catch (e) {}
    dronePopup = null;
  }
};

const clearRoutePreview = () => {
  const map = mapRef.value;
  if (!map) {
    // 如果地图实例不存在，清空标记引用数组但不尝试移除图层
    routeMarkerRefs.length = 0;
    routeLayerRef.value = null;
    return;
  }
  if (routeLayerRef.value) {
    try {
      map.removeLayer(routeLayerRef.value);
    } catch (e) {}
    routeLayerRef.value = null;
  }
  // 创建一个副本以避免迭代过程中修改数组
  const markersToRemove = [...routeMarkerRefs];
  routeMarkerRefs.length = 0; // 先清空数组，避免后续操作使用无效标记

  markersToRemove.forEach((marker) => {
    try {
      // 添加额外检查确保标记仍然连接到地图
      if (marker && map.hasLayer && map.hasLayer(marker)) {
        map.removeLayer(marker);
      }
    } catch (e) {
      // 静默处理移除错误
    }
  });
};

const resetRouteEditing = () => {
  const editingRouteId = routeForm.id; // 保存正在编辑的航线ID

  routeDrawingActive.value = false;
  clearRoutePreview();
  routeForm.waypoints = [];
  routeForm.name = "";
  routeForm.description = "";
  routeForm.duration = "";
  routeEditingIndex.value = null;
  selectedRoute.value = null;
  delete routeForm.id; // 清除编辑模式标记
  mapRef.value?.dragging?.enable();

  // 如果有正在编辑的航线，重新显示它
  if (editingRouteId && displayedRoutes.value.length >= 0) {
    // 延迟一下，确保编辑标记已清除
    setTimeout(() => {
      const routeToReload = routes.value.find((r) => r.id === editingRouteId);
      if (routeToReload && mapRef.value) {
        displayRouteOnMap(routeToReload);
      }
    }, 100);
  }
};

const clearFencePreview = () => {
  const map = mapRef.value;
  if (!map) return;
  if (fenceLayerRef.value) {
    try {
      map.removeLayer(fenceLayerRef.value);
    } catch (e) {}
    fenceLayerRef.value = null;
  }
  while (fenceMarkerRefs.length) {
    const marker = fenceMarkerRefs.pop();
    try {
      map.removeLayer(marker);
    } catch (e) {}
  }
};

const resetFenceEditing = () => {
  fenceDrawingActive.value = false;
  clearFencePreview();
  fenceForm.points = [];
  fenceForm.centerLat = "";
  fenceForm.centerLng = "";
  fenceForm.radius = 200;
  fenceForm.altitude = 120;
  fenceEditingIndex.value = null;
  mapRef.value?.dragging?.enable();
  // 清除围栏ID，确保下次是新建操作
  delete fenceForm.id;
};
const focusWaypoint = (index) => {
  routeEditingIndex.value = index;
  nextTick(() => {
    const container = document.getElementById(`waypoint-${index}`);
    if (container) {
      container.scrollIntoView({ behavior: "smooth", block: "center" });
      const input = container.querySelector("input.route-input");
      if (input) input.focus();
    }
  });
};

const setMarkerEditable = (marker, editable) => {
  if (!marker) return;
  if (editable) {
    marker.dragging.enable();
    marker._icon?.classList.add("editable");
  } else {
    marker.dragging.disable();
    marker._icon?.classList.remove("editable");
  }
};

const toggleMarkerEditing = (index) => {
  const map = mapRef.value;
  if (!map) return;
  const currentlyEditing = routeEditingIndex.value === index;
  routeEditingIndex.value = currentlyEditing ? null : index;
  routeMarkerRefs.forEach((ref, idx) => {
    if (ref && ref.dragging) {
      setMarkerEditable(ref, routeEditingIndex.value === idx);
    }
  });
  if (routeEditingIndex.value != null) {
    map.dragging?.disable();
    focusWaypoint(routeEditingIndex.value);
  } else {
    map.dragging?.enable();
  }
};
const focusFencePoint = (index) => {
  fenceEditingIndex.value = index;
  nextTick(() => {
    const container = document.getElementById(`fence-point-${index}`);
    if (container) {
      container.scrollIntoView({ behavior: "smooth", block: "center" });
      const input = container.querySelector("input.route-input");
      if (input) input.focus();
    }
  });
};

const setFenceMarkerEditable = (marker, editable) => {
  if (!marker) return;
  if (editable) {
    marker.dragging.enable();
    marker._icon?.classList.add("editable");
  } else {
    marker.dragging.disable();
    marker._icon?.classList.remove("editable");
  }
};

const toggleFenceMarkerEditing = (index) => {
  const map = mapRef.value;
  if (!map) return;
  const currentlyEditing = fenceEditingIndex.value === index;
  fenceEditingIndex.value = currentlyEditing ? null : index;
  fenceMarkerRefs.forEach((ref, idx) => {
    if (ref && ref.dragging) {
      setFenceMarkerEditable(ref, fenceEditingIndex.value === idx);
    }
  });
  if (fenceEditingIndex.value != null) {
    map.dragging?.disable();
    focusFencePoint(fenceEditingIndex.value);
  } else {
    map.dragging?.enable();
  }
};

const handleFencePointChange = (index, field, value) => {
  const point = fenceForm.points[index];
  if (!point) return;
  if (field === "lat" || field === "lng") {
    const num = Number(value);
    if (Number.isFinite(num)) {
      point[field] = num;
    }
  } else {
    point[field] = value;
  }
  renderFencePreview();
};

const removeFencePoint = (index) => {
  fenceForm.points.splice(index, 1);
  if (fenceEditingIndex.value === index) {
    fenceEditingIndex.value = null;
  } else if (
    fenceEditingIndex.value != null &&
    fenceEditingIndex.value > index
  ) {
    fenceEditingIndex.value -= 1;
  }
  renderFencePreview();
};

const updateFenceFromCircle = ({ lat, lng, radius }) => {
  fenceForm.centerLat = Number(lat).toFixed(6);
  fenceForm.centerLng = Number(lng).toFixed(6);
  fenceForm.radius = Number(radius).toFixed(2);
  renderFencePreview();
};

const renderRoutePreview = () => {
  const map = mapRef.value;
  map.pm.setLang("zh");
  if (!map) return;
  clearRoutePreview();
  if (!routeForm.waypoints.length) return;
  const points = routeForm.waypoints
    .map((wp, idx) => {
      const lat = Number(wp.lat);
      const lng = Number(wp.lng);
      if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;
      return {
        latlng: [lat, lng],
        name: (wp.name || `航点${idx + 1}`).trim(),
        altitude: Number(wp.altitude) || 0,
      };
    })
    .filter(Boolean);
  if (!points.length) return;
  routeLayerRef.value = L.polyline(
    points.map((item) => item.latlng),
    {
      color: "#ff7a45",
      weight: 3,
      opacity: 0.85,
    }
  ).addTo(map);
  points.forEach((point, order) => {
    const marker = L.marker(point.latlng, {
      draggable: true,
      icon: L.divIcon({
        className: "route-waypoint-marker",
        html: `<div class="route-waypoint-inner"><span>${
          order + 1
        }</span></div>`,
        iconSize: [30, 30],
        iconAnchor: [15, 15],
      }),
    })
      .addTo(map)
      .bindTooltip(
        `<div><div>名称： ${
          point.name
        }</div><div>纬度：${point.latlng[0].toFixed(
          6
        )}</div><div>经度：${point.latlng[1].toFixed(6)}</div><div>高度：${
          point.altitude || defaultPointHeight
        }m</div></div>`,
        {
          direction: "top",
          offset: [0, -14],
        }
      );
    marker.on("contextmenu", (evt) => {
      updateWaypointFromMarker(order, evt.latlng);
      renderRoutePreview();
    });
    marker.dragging.disable();
    marker.on("dragend", (evt) => {
      updateWaypointFromMarker(order, evt.target.getLatLng());
      renderRoutePreview();
    });
    marker.on("click", (evt) => {
      L.DomEvent.stop(evt);
      toggleMarkerEditing(order);
    });
    routeMarkerRefs.push(marker);
  });
  if (routeEditingIndex.value != null) {
    const activeMarker = routeMarkerRefs[routeEditingIndex.value];
    setMarkerEditable(activeMarker, true);
    // 保持地图拖动功能可用，不限制用户移动地图
  } else {
    // 确保地图拖动功能始终启用
  }
  map.dragging?.enable(); // 明确启用地图拖动功能
  // 移除了自动调整地图视野的功能，保持用户当前视图
};

const renderFencePreview = () => {
  const map = mapRef.value;
  if (!map) return;
  clearFencePreview();
  if (fenceForm.type === "polygon") {
    const points = fenceForm.points
      .map((pt, idx) => {
        const lat = Number(pt.lat);
        const lng = Number(pt.lng);
        if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;
        return {
          index: idx,
          latlng: [lat, lng],
          name: (pt.name || `围栏点${idx + 1}`).trim(),
        };
      })
      .filter(Boolean);
    if (!points.length) return;
    fenceLayerRef.value = L.polygon(
      points.map((p) => p.latlng),
      {
        color: "#ff4d4f",
        weight: 2,
        fillColor: "#ff4d4f",
        fillOpacity: 0.18,
      }
    ).addTo(map);
    points.forEach((point) => {
      const marker = L.marker(point.latlng, {
        draggable: true,
        icon: L.divIcon({
          className: "route-waypoint-marker",
          html: `<div class="route-waypoint-inner"><span>${
            point.index + 1
          }</span></div>`,
          iconSize: [30, 30],
          iconAnchor: [15, 15],
        }),
      })
        .addTo(map)
        .bindTooltip(`围栏点 ${point.index + 1}`, {
          direction: "top",
          offset: [0, -14],
        });
      marker.dragging.disable();
      marker.on("dragend", (evt) => {
        const { lat, lng } = evt.target.getLatLng();
        handleFencePointChange(point.index, "lat", lat);
        handleFencePointChange(point.index, "lng", lng);
      });
      marker.on("click", (evt) => {
        L.DomEvent.stop(evt);
        toggleFenceMarkerEditing(point.index);
      });
      marker.on("contextmenu", (evt) => {
        handleFencePointChange(point.index, "lat", evt.latlng.lat);
        handleFencePointChange(point.index, "lng", evt.latlng.lng);
      });
      fenceMarkerRefs.push(marker);
    });
    const centroid = points.reduce(
      (acc, cur) => {
        acc.lat += cur.latlng[0];
        acc.lng += cur.latlng[1];
        return acc;
      },
      { lat: 0, lng: 0 }
    );
    centroid.lat /= points.length;
    centroid.lng /= points.length;
    const labelMarker = L.marker([centroid.lat, centroid.lng], {
      interactive: false,
      icon: L.divIcon({
        className: "fence-label",
        html: `<div class="fence-label-inner">${
          fenceForm.name || "围栏"
        }</div>`,
        iconSize: [120, 32],
        iconAnchor: [60, -10],
      }),
    }).addTo(map);
    fenceMarkerRefs.push(labelMarker);
    try {
      map.fitBounds(fenceLayerRef.value.getBounds(), { padding: [40, 40] });
    } catch (e) {}
  } else if (fenceForm.type === "circle") {
    console.log(fenceForm);
    const lat = Number(fenceForm.centerLat);
    const lng = Number(fenceForm.centerLng);
    const radius = Number(fenceForm.radius);
    if (!Number.isFinite(lat) || !Number.isFinite(lng) || radius <= 0) return;
    fenceLayerRef.value = L.circle([lat, lng], {
      radius,
      color: "#ff4d4f",
      weight: 2,
      fillColor: "#ff4d4f",
      fillOpacity: 0.18,
    }).addTo(map);
    const marker = L.marker([lat, lng], {
      draggable: true,
      icon: L.divIcon({
        className: "route-waypoint-marker",
        html: '<div class="route-waypoint-inner"><span>C</span></div>',
        iconSize: [30, 30],
        iconAnchor: [15, 15],
      }),
    })
      .addTo(map)
      .bindTooltip(
        `<div><div>名称： ${fenceForm.name}</div><div>纬度：${fenceForm.centerLat}</div><div>经度：${fenceForm.centerLng}</div><div>半径：${fenceForm.radius}m</div></div>`,
        { direction: "top", offset: [0, -14] }
      );
    marker.dragging.disable();
    marker.on("dragend", (evt) => {
      const { lat: nLat, lng: nLng } = evt.target.getLatLng();
      updateFenceFromCircle({ lat: nLat, lng: nLng, radius });
    });
    marker.on("click", (evt) => {
      L.DomEvent.stop(evt);
      toggleFenceMarkerEditing(0);
    });
    fenceMarkerRefs.push(marker);
    const labelMarker = L.marker([lat, lng], {
      interactive: false,
      icon: L.divIcon({
        className: "fence-label",
        html: `<div class="fence-label-inner">${
          fenceForm.name || "围栏"
        }</div>`,
        iconSize: [120, 32],
        iconAnchor: [60, -20],
      }),
    }).addTo(map);
    fenceMarkerRefs.push(labelMarker);
    try {
      map.fitBounds(fenceLayerRef.value.getBounds(), { padding: [40, 40] });
    } catch (e) {}
  }
};

const activateDrawingTool = (toolId) => {
  const map = mapRef.value;
  if (!map?.pm) return;
  const config = TOOL_CONFIG[toolId];
  if (!config) return;
  disableDrawingControls();
  map.pm.setGlobalOptions?.({ continueDrawing: false });
  map.__flightPathDrawing = !!config.flight;
  map.pm.enableDraw(config.type, config.options || {});
};

const handleDrawEnd = () => {
  disableDrawingControls();
  if (activeTool.value === "route") {
    routeDrawingActive.value = false;
    if (routeForm.waypoints.length) {
      renderRoutePreview();
    }
  } else if (activeTool.value === "fence") {
    fenceDrawingActive.value = false;
    renderFencePreview();
  }
};
const startRouteDrawing = () => {
  const map = mapRef.value;
  if (!map?.pm) return;
  if (activeTool.value !== "route") {
    activeTool.value = "route";
    emit("tool-click", "route");
  }
  routeDrawingActive.value = true;
  disableDrawingControls();
  routeForm.defaultAltitude = Number(routeForm.defaultAltitude) || 120;
  routeForm.waypoints = [];
  clearRoutePreview();
  map.pm.setGlobalOptions?.({ continueDrawing: false });
  map.__flightPathDrawing = true;
  map.pm.enableDraw("Line", TOOL_CONFIG.route.options || {});
};

const startFenceDrawing = () => {
  const map = mapRef.value;
  if (!map?.pm) return;
  if (activeTool.value !== "fence") {
    activeTool.value = "fence";
    emit("tool-click", "fence");
  }
  fenceDrawingActive.value = true;
  fenceEditingIndex.value = null;
  map.dragging?.enable();
  disableDrawingControls();
  clearFencePreview();
  if (fenceForm.type === "polygon") {
    fenceForm.points = [];
    map.pm.enableDraw("Polygon", {
      allowSelfIntersection: false,
      continueDrawing: false,
      pathOptions: { color: "#22d3ee", weight: 2 },
      templineStyle: { color: "#22d3ee" },
    });
  } else {
    map.pm.enableDraw("Circle", {
      pathOptions: { color: "#10b981" },
    });
  }
};

const clearRoutePlanning = () => {
  routeForm.waypoints = [];
  routeForm.defaultAltitude = 120;
  routeForm.name = "";
  routeForm.description = "";
  routeForm.duration = "";
  clearRoutePreview();
  renderRoutePreview();
};

const clearFencePlanning = () => {
  fenceForm.points = [];
  fenceForm.centerLat = "34.24567";
  fenceForm.centerLng = "108.946835";
  fenceForm.radius = 200;
  fenceForm.altitude = 120;
  clearFencePreview();
  renderFencePreview();
};

const handleFenceTypeChange = (type) => {
  fenceForm.type = type;
  resetFenceEditing();
  if (type === "polygon") {
    fenceForm.points = [];
  } else {
    const map = mapRef.value;
    const center = map?.getCenter?.();
    fenceForm.centerLat = center ? center.lat.toFixed(6) : "";
    fenceForm.centerLng = center ? center.lng.toFixed(6) : "";
    fenceForm.radius = 200;
  }
  renderFencePreview();
};

const handleFenceFieldChange = (field, value) => {
  if (
    field === "centerLat" ||
    field === "centerLng" ||
    field === "radius" ||
    field === "altitude"
  ) {
    fenceForm[field] = value;
    renderFencePreview();
    return;
  }
  fenceForm[field] = value;
};

const submitFencePlan = async () => {
  if (fenceForm.type === "polygon" && !fenceForm.points.length) {
    ElMessage.warning("请先绘制围栏边界");
    return;
  }
  if (
    fenceForm.type === "circle" &&
    (!fenceForm.centerLat || !fenceForm.centerLng || !fenceForm.radius)
  ) {
    ElMessage.warning("请输入完整的围栏信息");
    return;
  }

  try {
    // 构造请求数据，根据围栏类型调整格式
    let payload = {
      name: fenceForm.name || `围栏${Date.now()}`,
      description: fenceForm.description || "",
      zone_type: fenceForm.type,
      max_altitude: Number(fenceForm.altitude) || 0,
      active: !!fenceForm.active,
      color: "#ff0000", // 默认红色
    };

    // 根据围栏类型设置坐标数据
    if (fenceForm.type === "polygon") {
      // 转换为后端需要的格式：[[lng, lat], [lng, lat], ...]
      payload.polygon_points = fenceForm.points.map((pt) => [
        Number(pt.lng),
        Number(pt.lat),
      ]);
    } else if (fenceForm.type === "circle") {
      payload.center_latitude = Number(fenceForm.centerLat);
      payload.center_longitude = Number(fenceForm.centerLng);
      payload.radius = Number(fenceForm.radius);
    }

    // 根据是否有id决定是新建还是修改围栏
    let response;
    if (fenceForm.id) {
      response = await noFlyZoneService.updateNoFlyZone(
        fenceForm.id,
        payload
      );
    } else {
      response = await noFlyZoneService.createNoFlyZone(payload);
    }

    const isSuccess =
      response?.code === undefined || response?.code === 200 || response?.success;

    if (!isSuccess) {
      throw new Error(response?.message || "保存失败");
    }

    ElMessage.success("围栏已成功保存到数据库");
    await refreshCustomNoFlyZones();
    resetFenceEditing();
  } catch (error) {
    console.error("保存围栏失败:", error);
    ElMessage.error(error.message || "保存围栏失败，请检查网络连接");
  }
};

const handleWaypointFieldChange = (index, field, value) => {
  const waypoint = routeForm.waypoints[index];
  if (!waypoint) return;
  if (field === "lat" || field === "lng" || field === "altitude") {
    const num = Number(value);
    if (Number.isFinite(num)) {
      waypoint[field] = num;
    }
  } else {
    waypoint[field] = value;
  }
  renderRoutePreview();
};

const removeWaypoint = (index) => {
  routeForm.waypoints.splice(index, 1);
  if (routeEditingIndex.value === index) {
    routeEditingIndex.value = null;
  } else if (
    routeEditingIndex.value != null &&
    routeEditingIndex.value > index
  ) {
    routeEditingIndex.value -= 1;
  }
  renderRoutePreview();
};

const updateWaypointFromMarker = (order, latlng) => {
  const waypoint = routeForm.waypoints[order];
  if (!waypoint) return;
  waypoint.lat = Number(latlng.lat.toFixed(6));
  waypoint.lng = Number(latlng.lng.toFixed(6));
};

const downloadRouteKml = () => {
  downloadKml(routeForm);
};

const submitRoutePlan = async () => {
  if (!routeForm.waypoints.length) {
    ElMessage.warning("请先绘制航线并生成航点");
    return;
  }
  console.log("Submitting route plan:", JSON.parse(JSON.stringify(routeForm)));
  // 准备请求数据
  const formData = {
    name: routeForm.name,
    drone_id: routeForm.drone_id,
    estimated_duration: routeForm.duration,
    description: routeForm.description,
    waypoints: routeForm.waypoints.map((wp, idx) => {
      return {
        alt: Number(wp.altitude) || 0,
        lat: wp.lat,
        lng: wp.lng,
        name: (wp.name || `航点${idx + 1}`).trim(),
      };
    }),
  };

  try {
    await flightRouteService.createRoute(formData);
    ElMessage.success("航线已提交");
    resetRouteEditing();
  } catch (error) {
    console.error("操作失败:", error);
    ElMessage.error(error.message || "操作失败");
  }
};

const onRouteFieldUpdate = ({ field, value }) => {
  if (!field) return;
  routeForm[field] = value;
};

const onRouteWaypointFieldUpdate = ({ index, field, value }) => {
  if (index == null || index < 0 || !field) return;
  handleWaypointFieldChange(index, field, value);
};

const onFenceFieldUpdate = ({ field, value }) => {
  if (!field) return;
  handleFenceFieldChange(field, value);
};

const onFencePointFieldUpdate = ({ index, field, value }) => {
  if (index == null || index < 0 || !field) return;
  handleFencePointChange(index, field, value);
};

const resetActiveTool = () => {
  disableDrawingControls();
  activeTool.value = null;
  resetRouteEditing();
  resetFenceEditing();
  routeSelectorVisible.value = false;
  clearDisplayedRoute();
};

const handleToolClick = (toolId, forceOpen = false) => {
  if (!forceOpen && activeTool.value === toolId) {
    resetActiveTool();
    emit("tool-click", null);
    return;
  }
  resetActiveTool();
  activeTool.value = toolId;
  emit("tool-click", toolId);
  clearActiveTaskLayers();
  if (toolId === "route") {
    renderRoutePreview();
    return;
  }
  if (toolId === "fence") {
    renderFencePreview();
    return;
  }
  if (toolId === "measure") {
    enableDrawingControls();
    return;
  }
  activateDrawingTool(toolId);
};

// 打开航线选择器
const openRouteSelector = () => {
  if (routes.value.length === 0) {
    fetchRoutes();
  }
  selectedRoutes.value = []; // 每次打开时清空选择列表
  routeSelectorVisible.value = true;
};

// 处理航线更新事件
const handleRouteUpdated = (updatedRoute) => {
  // 更新routes列表中的航线数据
  const index = routes.value.findIndex((r) => r.id === updatedRoute.id);
  if (index > -1) {
    routes.value[index] = updatedRoute;
  }

  // 更新或重新显示地图上的航线
  if (updatedRoute.id && displayedRoutes.value.length >= 0) {
    // 延迟一下，确保编辑标记已清除
    setTimeout(() => {
      // 清除旧的航线显示
      clearSingleRoute(updatedRoute.id);
      // 显示更新后的航线
      displayRouteOnMap(updatedRoute);
    }, 100);
  }
};

// 编辑选中的航线的函数在文件下方（1317行）

// 获取航线列表
const fetchRoutes = async () => {
  try {
    const data = await flightRouteService.getRoutes({
      page_size: 100,
    });

    const items = data?.items || [];

    routes.value = items.map((route) => ({
      ...route,
      waypoint_count: route.waypoints?.length || 0,
    }));
    filterRoutes();
  } catch (error) {
    console.error("获取航线列表失败:", error);
    ElMessage.error("获取航线列表失败");
  }
};

// 筛选航线
const filterRoutes = () => {
  if (!routeSearchQuery.value.trim()) {
    filteredRoutes.value = routes.value;
  } else {
    const query = routeSearchQuery.value.toLowerCase();
    filteredRoutes.value = routes.value.filter((route) =>
      route.name.toLowerCase().includes(query)
    );
  }
};

// 切换航线选择状态
const toggleRouteSelection = (route) => {
  const index = selectedRoutes.value.findIndex((r) => r.id === route.id);
  if (index > -1) {
    // 如果已选中，则取消选择
    selectedRoutes.value.splice(index, 1);
  } else {
    // 如果未选中，则添加到选择列表
    selectedRoutes.value.push(route);
  }
};

// 确认选择并显示所有选中的航线
const confirmRouteSelection = () => {
  if (selectedRoutes.value.length === 0) {
    routeSelectorVisible.value = false;
    return;
  }

  // 清除之前显示的航线
  clearDisplayedRoute();

  // 显示所有选中的航线
  selectedRoutes.value.forEach((route) => {
    displayRouteOnMap(route);
  });

  routeSelectorVisible.value = false;
};

// 在地图上显示单个航线
const displayRouteOnMap = (route) => {
  const map = mapRef.value;
  if (!map || !route.waypoints || !route.waypoints.length) return;

  // 生成随机颜色以区分不同航线
  const colors = [
    "#2563eb",
    "#dc2626",
    "#059669",
    "#d97706",
    "#7c3aed",
    "#db2777",
  ];
  const colorIndex = displayedRoutes.value.length % colors.length;
  const color = colors[colorIndex];

  // 创建航线线条
  const points = route.waypoints.map((wp) => [wp.lat, wp.lng]);
  const routeLayer = L.polyline(points, {
    color: color,
    weight: 4,
    opacity: 0.9,
    dashArray: "10, 5",
  }).addTo(map);

  // 添加点击事件，点击航线进入编辑模式
  routeLayer.on("click", (evt) => {
    L.DomEvent.stop(evt);
    editSelectedRoute(route);
  });

  // 创建航点标记
  const markers = [];
  route.waypoints.forEach((wp, index) => {
    const marker = L.marker([wp.lat, wp.lng], {
      icon: L.divIcon({
        className: "route-waypoint-marker",
        html: `<div class="route-waypoint-inner" style="background-color: ${color};"><span>${
          index + 1
        }</span></div>`,
        iconSize: [30, 30],
        iconAnchor: [15, 15],
      }),
    }).addTo(map);

    // 航点点击事件，点击进入编辑模式
    marker.on("click", (evt) => {
      L.DomEvent.stop(evt);
      editSelectedRoute(route);
    });

    marker.bindPopup(`
      <div class="waypoint-popup">
        <div><strong>航点 ${index + 1}</strong></div>
        <div>航线: ${route.name}</div>
        <div>纬度: ${wp.lat}</div>
        <div>经度: ${wp.lng}</div>
        <div>高度: ${wp.alt || 0}m</div>
        <div style="margin-top: 8px;">
          <button style="background: ${color}; color: white; border: none; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 12px;" onclick="event.stopPropagation();">编辑航线</button>
        </div>
      </div>
    `);

    markers.push(marker);
  });

  // 存储航线图层信息
  displayedRoutes.value.push({
    id: route.id,
    name: route.name,
    layer: routeLayer,
    markers: markers,
    color: color,
    waypoints: route.waypoints, // 保存航点信息，用于后续更新标记位置
  });

  // 移除了地图自动缩放的功能，保持当前地图视图
  // 直接更新标记位置以确保标记正确显示
  setTimeout(() => {
    displayedRoutes.value.forEach((routeInfo) => {
      if (routeInfo.markers && routeInfo.markers.length > 0) {
        // 移除旧标记
        routeInfo.markers.forEach((marker, index) => {
          try {
            map.removeLayer(marker);
          } catch (e) {}
        });

        // 创建新标记
        const newMarkers = [];
        const route = displayedRoutes.value.find((r) => r.id === routeInfo.id);
        if (route && route.waypoints) {
          route.waypoints.forEach((wp, index) => {
            const newMarker = L.marker([wp.lat, wp.lng], {
              icon: L.divIcon({
                className: "route-waypoint-marker",
                html: `<div class="route-waypoint-inner" style="background-color: ${
                  routeInfo.color
                };"><span>${index + 1}</span></div>`,
                iconSize: [30, 30],
                iconAnchor: [15, 15],
              }),
            }).addTo(map);

            // 绑定点击事件
            newMarker.on("click", (evt) => {
              L.DomEvent.stop(evt);
              editSelectedRoute(route);
            });

            // 绑定弹窗
            newMarker.bindPopup(`
              <div class="waypoint-popup">
                <div><strong>航点 ${index + 1}</strong></div>
                <div>航线: ${route.name}</div>
                <div>纬度: ${wp.lat}</div>
                <div>经度: ${wp.lng}</div>
                <div>高度: ${wp.alt || 0}m</div>
                <div style="margin-top: 8px;">
                  <button style="background: ${
                    routeInfo.color
                  }; color: white; border: none; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 12px;" onclick="event.stopPropagation();">编辑航线</button>
                </div>
              </div>
            `);

            newMarkers.push(newMarker);
          });

          // 更新标记引用和保存航点信息
          routeInfo.markers = newMarkers;
          routeInfo.waypoints = route.waypoints;
        }
      }
    });
  }, 100); // 简短延迟，确保航线图层已添加完成
};

// 选择并显示单个航线（兼容原有功能）
const selectRouteForDisplay = (route) => {
  selectedRoute.value = route;
  selectedRoutes.value = [route]; // 同时更新多选列表
  clearDisplayedRoute();
  displayRouteOnMap(route);
  routeSelectorVisible.value = false;
};

// 清除显示的航线
const clearDisplayedRoute = () => {
  const map = mapRef.value;
  if (!map) return;

  // 移除所有显示的航线图层
  displayedRoutes.value.forEach((routeInfo) => {
    if (routeInfo.layer) {
      try {
        map.removeLayer(routeInfo.layer);
      } catch (e) {}
    }
    if (routeInfo.markers) {
      routeInfo.markers.forEach((marker) => {
        try {
          map.removeLayer(marker);
        } catch (e) {}
      });
    }
  });
  displayedRoutes.value = [];
};

// 清除单个航线
const clearSingleRoute = (routeId) => {
  const map = mapRef.value;
  if (!map) return;

  const index = displayedRoutes.value.findIndex((r) => r.id === routeId);
  if (index > -1) {
    const routeInfo = displayedRoutes.value[index];
    // 移除航线图层
    if (routeInfo.layer) {
      try {
        map.removeLayer(routeInfo.layer);
      } catch (e) {}
    }
    // 移除航点标记
    if (routeInfo.markers) {
      routeInfo.markers.forEach((marker) => {
        try {
          map.removeLayer(marker);
        } catch (e) {}
      });
    }
    // 从列表中移除
    displayedRoutes.value.splice(index, 1);
  }
};

// 检查航线是否被选中
const isRouteSelected = (routeId) => {
  return selectedRoutes.value.some((r) => r.id === routeId);
};

// 显示航线选择器
const showRouteSelector = () => {
  if (routes.value.length === 0) {
    fetchRoutes();
  }
  selectedRoutes.value = []; // 每次打开时清空选择列表
  routeSelectorVisible.value = true;
};

// 编辑选中的航线
const editSelectedRoute = (route) => {
  if (!route || !route.waypoints || !route.waypoints.length) return;

  selectedRoute.value = route;

  // 填充编辑表单
  routeForm.name = route.name || "";
  routeForm.description = route.description || "";
  routeForm.duration = route.duration || "";

  // 转换航点数据
  routeForm.waypoints = route.waypoints.map((wp, index) => ({
    id: wp.id || `${Date.now()}-${index}`,
    name: wp.name || `航点${index + 1}`,
    lat: wp.lat,
    lng: wp.lng,
    altitude: wp.alt || wp.altitude || 120,
  }));

  // 标记当前是编辑模式，并保存原始ID
  routeForm.id = route.id;

  // 激活航线编辑模式
  routeDrawingActive.value = true;

  // 清除正在编辑的航线的显示（但保留其他航线）
  clearSingleRoute(route.id);

  // 确保航线面板可见
  activeTool.value = "route";

  // 重新渲染预览
  renderRoutePreview();
};

const externallyActivateTool = (toolId) => {
  if (!toolId) {
    resetActiveTool();
    emit("tool-click", null);
    return;
  }
  handleToolClick(toolId, true);
};

const handleToolCenter = () => {
  const map = mapRef.value;
  if (!map) return;
  map.setView([34.24567, 108.906253], 14);
};

// 限飞区图层与状态
let noFlyLayer = null;
let noFlyFetchTimer = null;
let noFlyAbort = null;
const DRONE_TYPE = "dji-mavic-3";
const ZONE_LEVELS = "0,1,2,3,7,8,10";
const ZONE_MODE = "flysafe_website";

// 地址查询状态
const searchKeyword = ref("");
const searchResults = ref([]);
const searchLoading = ref(false);
const searchError = ref("");
let searchMarker = null;
let zoomRenderTimer = null;
let moveRenderTimer = null;

onBeforeUnmount(() => {
  // 清除定时器
  if (zoomRenderTimer) clearTimeout(zoomRenderTimer);
  if (moveRenderTimer) clearTimeout(moveRenderTimer);
  // 先清理所有图层和编辑状态
  resetRouteEditing();
  resetFenceEditing();
  clearDisplayedRoute();

  if (mapRef.value) {
    // 移除所有标记
    clearActiveTaskLayers();
    clearPointMarkers(mapRef.value);

    // 移除所有事件监听器
    mapRef.value.off("pm:create", handleDrawCreate);
    mapRef.value.off("pm:drawend", handleDrawEnd);
    mapRef.value.off("moveend", handleBoundsChange);

    // 移除特殊图层
    try {
      if (noFlyLayer) mapRef.value.removeLayer(noFlyLayer);
    } catch (e) {}

    // 最后移除地图实例
    mapRef.value.remove();
  }

  // 清空引用
  mapRef.value = null;
});

const initMap = () => {
  // 初始化地图
  const mapInstance = L.map("map", {
    center: [34.24567, 108.906253], // 地图中心
    zoom: 14, //缩放比列
    zoomControl: false, //禁用 + - 按钮
    doubleClickZoom: true, // 禁用双击放大
    attributionControl: false, // 移除右下角leaflet标识
  });

  // 添加地图缩放事件监听，确保标记位置正确更新
  mapInstance.on("zoomend", () => {
    // 在航线编辑模式或有显示航线的情况下都需要重新渲染标记
    if (
      (routeForm.waypoints.length > 0 && routePanelVisible.value) ||
      displayedRoutes.value.length > 0
    ) {
      // 使用setTimeout避免频繁重绘
      if (zoomRenderTimer) clearTimeout(zoomRenderTimer);
      zoomRenderTimer = setTimeout(() => {
        try {
          // 如果是编辑模式，重绘编辑中的航线标记
          if (routePanelVisible.value && routeForm.waypoints.length > 0) {
            renderRoutePreview();
          }
          // 如果有显示的航线，更新它们的标记位置
          if (displayedRoutes.value.length > 0) {
            updateDisplayedRouteMarkers();
          }
        } catch (error) {
          console.warn("缩放时更新标记失败:", error);
        }
      }, 100);
    }
  });

  // 添加地图移动结束事件监听
  mapInstance.on("moveend", () => {
    // 在航线编辑模式或有显示航线的情况下都需要重新渲染标记
    if (
      (routeForm.waypoints.length > 0 && routePanelVisible.value) ||
      displayedRoutes.value.length > 0
    ) {
      // 使用setTimeout避免频繁重绘
      if (moveRenderTimer) clearTimeout(moveRenderTimer);
      moveRenderTimer = setTimeout(() => {
        try {
          // 如果是编辑模式，重绘编辑中的航线标记
          if (routePanelVisible.value && routeForm.waypoints.length > 0) {
            renderRoutePreview();
          }
          // 如果有显示的航线，更新它们的标记位置
          if (displayedRoutes.value.length > 0) {
            updateDisplayedRouteMarkers();
          }
        } catch (error) {
          console.warn("移动时更新标记失败:", error);
        }
      }, 100);
    }
  });

  // 添加地图缩放动画开始事件监听，提前准备标记更新
  mapInstance.on("zoomstart", () => {
    // 可以在这里添加一些预处理逻辑
  });

  // 同步更新显示航线的标记位置的函数
  const updateDisplayedRouteMarkers = () => {
    const map = mapRef.value;
    if (!map) return;

    displayedRoutes.value.forEach((routeInfo) => {
      if (
        routeInfo.markers &&
        routeInfo.markers.length > 0 &&
        routeInfo.waypoints
      ) {
        // 创建新标记数组
        const newMarkers = [];

        // 先移除旧标记
        routeInfo.markers.forEach((marker) => {
          try {
            if (map.hasLayer && map.hasLayer(marker)) {
              map.removeLayer(marker);
            }
          } catch (e) {
            console.warn("移除标记失败:", e);
          }
        });

        // 然后创建并添加新标记
        routeInfo.waypoints.forEach((wp, index) => {
          const newMarker = L.marker([wp.lat, wp.lng], {
            icon: L.divIcon({
              className: "route-waypoint-marker",
              html: `<div class="route-waypoint-inner" style="background-color: ${
                routeInfo.color
              };"><span>${index + 1}</span></div>`,
              iconSize: [30, 30],
              iconAnchor: [15, 15],
            }),
          }).addTo(map);

          // 重新绑定事件
          newMarker.on("click", (evt) => {
            L.DomEvent.stop(evt);
            editSelectedRoute(routeInfo);
          });

          newMarker.bindPopup(`
            <div class="waypoint-popup">
              <div><strong>航点 ${index + 1}</strong></div>
              <div>航线: ${routeInfo.name}</div>
              <div>纬度: ${wp.lat}</div>
              <div>经度: ${wp.lng}</div>
              <div>高度: ${wp.alt || 0}m</div>
              <div style="margin-top: 8px;">
                <button style="background: ${
                  routeInfo.color
                }; color: white; border: none; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 12px;" onclick="event.stopPropagation();">编辑航线</button>
              </div>
            </div>
          `);

          newMarkers.push(newMarker);
        });

        // 更新标记引用
        routeInfo.markers = newMarkers;
      }
    });
  };

  // 将函数暴露给外部作用域，以便其他地方也能调用
  window.updateDisplayedRouteMarkers = updateDisplayedRouteMarkers;

  // // 添加天地图矢量图底图
  let vector_img = L.tileLayer(
    "http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=b96f5225ccf95b9dff787409324753ce",
    {
      maxZoom: 18,
      subdomains: [0, 1, 2, 3, 4, 5, 6, 7],
    }
  );

  //矢量注记
  const vector_cia = L.tileLayer(
    "http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=b96f5225ccf95b9dff787409324753ce",
    {
      subdomains: [0, 1, 2, 3, 4, 5, 6, 7],
    }
  );

  // // 天地图墨卡托
  //底图
  const image = L.tileLayer(
    "http://t{s}.tianditu.gov.cn/img_w/wmts?tk=b96f5225ccf95b9dff787409324753ce&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}",
    {
      subdomains: [0, 1, 2, 3, 4, 5, 6, 7],
    }
  );
  //注记
  const cia = L.tileLayer(
    "http://t{s}.tianditu.gov.cn/cia_w/wmts?tk=b96f5225ccf95b9dff787409324753ce&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}",
    {
      subdomains: [0, 1, 2, 3, 4, 5, 6, 7],
      transparent: true,
      zIndex: 3,
    }
  );
  // //天地图图组
  const tiandiMap = L.layerGroup([image, cia]);
  const vectorMap = L.layerGroup([vector_img, vector_cia]);
  const baseLayers = {
    影像底图: tiandiMap,
    矢量底图: vectorMap,
  };
  var layerControl = L.control.layers(baseLayers, null, {
    position: "bottomright",
  });
  layerControl.addTo(mapInstance);
  mapInstance.addLayer(tiandiMap);
  L.control
    .zoom({
      position: "bottomright", // 设置控件位置
    })
    .addTo(mapInstance);

  //绘制监听
  mapRef.value = mapInstance;
  mapInstance.on("pm:create", handleDrawCreate);
  mapInstance.on("pm:drawend", handleDrawEnd);
  // 限飞区：添加图层并监听视图变化
  noFlyLayer = L.layerGroup();
  noFlyLayer.addTo(mapInstance);
  mapInstance.on("moveend", handleBoundsChange);
  // 地图加载完成后立即绘制当前视图的禁飞区（所有页面均启用）
  fetchAndRenderNoFlyZones();
};

const handleDrawCreate = (e) => {
  const mapInstance = mapRef.value;
  if (!mapInstance) return;
  // 允许页面级绘制（如电子围栏/航线编辑）抑制全局处理
  if (mapInstance.__suppressGlobalCreate) {
    mapInstance.__suppressGlobalCreate = false;
    return;
  }
  const { layer, shape } = e;
  if (activeTool.value === "route" && shape === "Line") {
    const latlngs = normaliseLatLngs(layer?.getLatLngs?.());
    try {
      mapInstance.removeLayer(layer);
    } catch (err) {}
    if (latlngs.length) {
      routeForm.waypoints = latlngs.map((point, index) => {
        const lat = Number(point.lat ?? point[0]);
        const lng = Number(point.lng ?? point[1]);
        return {
          id: `${Date.now()}-${index}`,
          name: `航点${index + 1}`,
          lat,
          lng,
          altitude: routeForm.defaultAltitude || 120,
        };
      });
      renderRoutePreview();
    }
    routeDrawingActive.value = false;
    disableDrawingControls();
    emit("tool-click", "route");
    return;
  }
  if (activeTool.value === "fence") {
    if (
      fenceForm.type === "polygon" &&
      (shape === "Polygon" || shape === "Polyline")
    ) {
      const latlngs = normaliseLatLngs(layer?.getLatLngs?.());
      try {
        mapInstance.removeLayer(layer);
      } catch (err) {}
      if (latlngs.length) {
        fenceForm.points = latlngs.map((point, index) => {
          const lat = Number(point.lat ?? point[0]);
          const lng = Number(point.lng ?? point[1]);
          return {
            id: `${Date.now()}-${index}`,
            name: `围栏点${index + 1}`,
            lat,
            lng,
          };
        });
        fenceDrawingActive.value = false;
        renderFencePreview();
      }
      return;
    }
    if (fenceForm.type === "circle" && shape === "Circle") {
      const center = layer?.getLatLng?.();
      const radius = layer?.getRadius?.();
      try {
        mapInstance.removeLayer(layer);
      } catch (err) {}
      if (
        center &&
        Number.isFinite(center.lat) &&
        Number.isFinite(center.lng)
      ) {
        fenceForm.centerLat = center.lat.toFixed(6);
        fenceForm.centerLng = center.lng.toFixed(6);
        fenceForm.radius = Number(radius || fenceForm.radius || 200).toFixed(2);
        fenceDrawingActive.value = false;
        renderFencePreview();
      }
      return;
    }
  }
  if (shape === "Line") {
    const latlngs = normaliseLatLngs(layer?.getLatLngs?.());
    if (latlngs.length) {
      if (!mapInstance.__flightPathDrawing) {
        L.polyline(latlngs).addTo(mapInstance).showMeasurements?.();
      }
      attachPointPopups(mapInstance, latlngs);
      //PathTrackPlayer(mapInstance, latlngs)
    }
    if (mapInstance.__flightPathDrawing) return;
  } else if (shape === "Circle") {
    clearPointMarkers(mapInstance);
    const { lat, lng } = layer?.getLatLng?.() || {};
    const radius = layer?.getRadius?.();
    if (lat != null && lng != null && radius != null) {
      L.circle([lat, lng], radius).addTo(mapInstance).showMeasurements?.();
    }
  } else if (shape === "Rectangle" || shape === "Polygon") {
    clearPointMarkers(mapInstance);
    const latlngs = normaliseLatLngs(layer?.getLatLngs?.());
    if (latlngs.length) {
      L.polygon(latlngs).addTo(mapInstance).showMeasurements?.();
    }
  }
};

const normaliseLatLngs = (latlngs) => {
  if (!latlngs) return [];
  const list = Array.isArray(latlngs[0]) ? latlngs.flat() : latlngs;
  return Array.isArray(list) ? list : [];
};

const normaliseFlightPath = (flightPath = []) =>
  flightPath
    .map((point) => {
      if (!point) return null;
      if (Array.isArray(point) && point.length >= 2) {
        const lat = Number(point[0]);
        const lng = Number(point[1]);
        return Number.isFinite(lat) && Number.isFinite(lng) ? [lat, lng] : null;
      }
      const lat = Number(point.lat ?? point.latitude);
      const lng = Number(point.lng ?? point.longitude);
      return Number.isFinite(lat) && Number.isFinite(lng) ? [lat, lng] : null;
    })
    .filter(Boolean);

const clearPointMarkers = (mapInstance) => {
  if (!mapInstance) return;
  while (pointMarkers.length) {
    const marker = pointMarkers.pop();
    mapInstance.removeLayer(marker);
  }
};

const attachPointPopups = (mapInstance, latlngs = []) => {
  clearPointMarkers(mapInstance);
  latlngs.forEach((latlng, index) => {
    const marker = L.circleMarker(latlng, {
      radius: 6,
      color: "#F7BA1E",
      weight: 2,
      fillColor: "#CC9213",
      fillOpacity: 0.8,
    });
    const { lat, lng } = latlng;
    const heightText =
      mapInstance?.__flightPathDefaultHeight || defaultPointHeight;
    marker.bindPopup(
      `<div><div>航点 ${index + 1}</div><div>纬度：${lat.toFixed(
        6
      )}</div><div>经度：${lng.toFixed(6)}</div><div>${heightText}</div></div>`
    );
    marker.addTo(mapInstance);
    pointMarkers.push(marker);
  });
};

const showTaskOnMap = ({ flightPath = [], drone, taskName } = {}) => {
  const map = mapRef.value;
  const droneIconUrl = new URL("@/assets/wurenji.png", import.meta.url).href;
  if (!map) return;
  clearActiveTaskLayers();
  const latlngs = normaliseFlightPath(flightPath);
  if (latlngs.length) {
    activeTaskRoute = L.polyline(latlngs, {
      color: "#2F88FF",
      weight: 3,
      opacity: 0.85,
    }).addTo(map);
    activeTaskRoute.bringToFront?.();
    latlngs.forEach((point, index) => {
      const marker = L.circleMarker(point, {
        radius: 5,
        color: "#2F88FF",
        fillColor: "#ffffff",
        fillOpacity: 1,
        weight: 2,
      })
        .addTo(map)
        .bindTooltip(`航点 ${index + 1}`, {
          direction: "top",
          offset: [0, -6],
        });
      taskWaypointMarkers.push(marker);
    });
    try {
      const bounds = activeTaskRoute.getBounds();
      if (
        drone &&
        Number.isFinite(Number(drone.latitude)) &&
        Number.isFinite(Number(drone.longitude))
      ) {
        bounds.extend([Number(drone.latitude), Number(drone.longitude)]);
      }
      map.fitBounds(bounds, { padding: [50, 50] });
    } catch (e) {}
  } else if (
    drone &&
    Number.isFinite(Number(drone.latitude)) &&
    Number.isFinite(Number(drone.longitude))
  ) {
    map.flyTo([Number(drone.latitude), Number(drone.longitude)], 15);
  }
  if (
    drone &&
    Number.isFinite(Number(drone.latitude)) &&
    Number.isFinite(Number(drone.longitude))
  ) {
    const latlng = [Number(drone.latitude), Number(drone.longitude)];
    const droneIcon = L.divIcon({
      className: "task-drone-icon",
      html: `<img src="${droneIconUrl}" style="width: 40px; height:40px" /><div class="drone-icon-inner">${
        drone.id || "DR"
      }</div>`,
      iconSize: [40, 40],
      iconAnchor: [20, 20],
    });
    activeDroneMarker = L.marker(latlng, { icon: droneIcon }).addTo(map);
    const popupHtml = `<div class="drone-popup">
        <div class="title">${
          taskName || drone.name || drone.id || "无人机"
        }</div>
        <div>纬度：${Number(drone.latitude).toFixed(6)}</div>
        <div>经度：${Number(drone.longitude).toFixed(6)}</div>
        <div>高度：${drone.altitude ?? "-"} m</div>
      </div>`;
    dronePopup = L.popup({
      closeButton: true,
      autoClose: false,
      closeOnClick: false,
    })
      .setLatLng(latlng)
      .setContent(popupHtml);
    map.openPopup(dronePopup);
    const handleClick = () => emit("drone-click", drone);
    activeDroneId = drone.id;
    activeDroneMarker.on("click", handleClick);
    activeDroneMarker.__clickHandler = handleClick;
  }
};

// ====== 启用绘图工具 ======
function enableDrawingControls() {
  const map = mapRef.value;
  if (!map || !map.pm) return;
  // 添加绘图控件（Leaflet.Geoman）
  map.pm.addControls({
    position: "topright",
    drawMarker: false,
    drawCircleMarker: false,
    drawPolyline: true,
    drawPolygon: true,
    drawRectangle: true,
    drawCircle: true,
    cutPolygon: false,
    drawText: false,
    editMode: true,
    dragMode: false,
    removalMode: true,
  });
  map.pm.setGlobalOptions?.({ continueDrawing: false });
  map.pm.setLang("zh");
  scheduleFetchNoFlyZones();
}

function disableDrawingControls() {
  const map = mapRef.value;
  if (!map || !map.pm) return;
  try {
    map.pm.removeControls();
  } catch (e) {}
  map.pm.disableDraw?.("Line");
  map.pm.disableDraw?.("Polygon");
  map.pm.disableDraw?.("Rectangle");
  map.pm.disableDraw?.("Circle");
  map.pm.disableGlobalEditMode?.();
  map.pm.disableGlobalDragMode?.();
  map.pm.disableGlobalRemovalMode?.();
}

watch(routePanelVisible, (visible) => {
  if (!visible) {
    resetRouteEditing();
  } else if (routeForm.waypoints.length) {
    renderRoutePreview();
  }
});

watch(fencePanelVisible, (visible) => {
  if (!visible) {
    resetFenceEditing();
  } else {
    renderFencePreview();
  }
});

watch(
  () => route.path,
  () => {
    scheduleFetchNoFlyZones();
  }
);

// ====== 限飞区：根据当前视图请求并绘制 ======
function handleBoundsChange() {
  scheduleFetchNoFlyZones();
}

function scheduleFetchNoFlyZones() {
  if (noFlyFetchTimer) clearTimeout(noFlyFetchTimer);
  noFlyFetchTimer = setTimeout(fetchAndRenderNoFlyZones, 400);
}

function clearNoFlyLayer() {
  if (!noFlyLayer) return;
  try {
    noFlyLayer.clearLayers();
  } catch (e) {}
}

// 从后端API获取自定义禁飞区数据

// 修复标记位置问题的辅助函数 - 确保标记与地图坐标系统同步
const syncMarkerPositions = () => {
  if (mapRef.value && routeMarkerRefs.length > 0) {
    // 简单地重新渲染整个预览，确保所有标记位置正确
    renderRoutePreview();
  }
};
async function fetchCustomNoFlyZones() {
  try {
    console.log("开始从后端获取自定义禁飞区...");
    const response = await noFlyZoneService.getNoFlyZones({
      page_size: 100,
    });

    const noFlyZones = response?.data?.items || response?.items || [];
    console.log(`成功获取 ${noFlyZones.length} 个自定义禁飞区`);
    return noFlyZones;
  } catch (error) {
    console.error("获取自定义禁飞区异常:", error);
    return [];
  }
}

// 渲染自定义禁飞区
function renderCustomNoFlyZones(noFlyZones) {
  const map = mapRef.value;
  if (!map || !noFlyLayer) return;

  noFlyZones.forEach((zone) => {
    try {
      // 根据禁飞区类型创建不同的图形
      if (zone.zone_type === "polygon" && zone.polygon_points) {
        // 多边形禁飞区，添加错误处理
        try {
          let polygonPoints;

          // 检查polygon_points是否已经是对象/数组类型
          if (typeof zone.polygon_points === "object") {
            polygonPoints = zone.polygon_points;
          } else {
            // 尝试解析JSON字符串
            polygonPoints = JSON.parse(zone.polygon_points);
          }

          // 确保是有效的点数组
          if (Array.isArray(polygonPoints) && polygonPoints.length > 2) {
            // 后端坐标格式是[lng, lat]，需要转换为Leaflet需要的[lat, lng]
            const convertedPoints = polygonPoints.map((point) => {
              if (Array.isArray(point) && point.length >= 2) {
                return [point[1], point[0]]; // [lat, lng]
              }
              return point;
            });
            const polygon = L.polygon(convertedPoints, {
              color: zone.color || "#ff0000",
              weight: 2,
              opacity: 0.8,
              fillOpacity: 0.3,
              fillColor: zone.color || "#ff0000",
            }).addTo(noFlyLayer);

            // 添加弹出信息
            const popupContent = `
              <div style="display: flex;align-items: center;gap: 6px;">
                <div>
                  <div>区域名称: ${zone.name || "自定义禁飞区"}</div>
                  <div>来源: 自定义</div>
                  <div>类型: 多边形</div>
                  <div>等级: ${zone.level || "无"}</div>
                  <div ${
                    zone.max_altitude > 0 ? "" : 'style="display:none"'
                  }>高度限制: ${zone.max_altitude} m</div>
                </div>
              </div>
            `;
            polygon.bindPopup(popupContent);

            // 添加点击事件处理
            polygon.on("click", (evt) => {
              L.DomEvent.stop(evt);
              // 填充围栏表单数据
              fillFenceFormFromZone(zone);
            });
          }
        } catch (jsonError) {
          console.warn(
            "多边形禁飞区JSON解析失败:",
            jsonError,
            "数据:",
            zone.polygon_points
          );
        }
      } else if (zone.zone_type === "circle" && zone.radius) {
        // 圆形禁飞区，支持两种坐标格式：lat/lng 和 center_latitude/center_longitude
        const centerLat = zone.lat || zone.center_latitude;
        const centerLng = zone.lng || zone.center_longitude;

        if (centerLat && centerLng) {
          const circle = L.circle([centerLat, centerLng], {
            radius: zone.radius, // 半径，单位：米
            color: zone.color || "#ff0000",
            weight: 2,
            opacity: 0.8,
            fillOpacity: 0.3,
            fillColor: zone.color || "#ff0000",
          }).addTo(noFlyLayer);

          // 添加弹出信息
          const popupContent = `
            <div style="display: flex;align-items: center;gap: 6px;">
              <div>
                <div>区域名称: ${zone.name || "自定义禁飞区"}</div>
                <div>来源: 自定义</div>
                <div>类型: 圆形</div>
                <div>半径: ${(zone.radius / 1000).toFixed(2)}km</div>
                <div>等级: ${zone.level || "无"}</div>
                <div ${
                  zone.max_altitude > 0 ? "" : 'style="display:none"'
                }>高度限制: ${zone.max_altitude} m</div>
              </div>
            </div>
          `;
          circle.bindPopup(popupContent);

          // 添加点击事件处理
          circle.on("click", (evt) => {
            L.DomEvent.stop(evt);
            // 填充围栏表单数据
            fillFenceFormFromZone(zone);
          });
        }
      } else if (zone.zone_type === "polyline" && zone.polygon_points) {
        // 线形禁飞区，添加错误处理
        try {
          let polylinePoints;

          // 检查polygon_points是否已经是对象/数组类型
          if (typeof zone.polygon_points === "object") {
            polylinePoints = zone.polygon_points;
          } else {
            // 尝试解析JSON字符串
            polylinePoints = JSON.parse(zone.polygon_points);
          }

          if (Array.isArray(polylinePoints) && polylinePoints.length > 1) {
            // 后端坐标格式是[lng, lat]，需要转换为Leaflet需要的[lat, lng]
            const convertedPoints = polylinePoints.map((point) => {
              if (Array.isArray(point) && point.length >= 2) {
                return [point[1], point[0]]; // [lat, lng]
              }
              return point;
            });
            const polyline = L.polyline(convertedPoints, {
              color: zone.color || "#ff0000",
              weight: 4,
              opacity: 0.8,
              dashArray: "5,5",
            }).addTo(noFlyLayer);

            // 添加弹出信息
            const popupContent = `
              <div style="display: flex;align-items: center;gap: 6px;">
                <div>
                  <div>区域名称: ${zone.name || "自定义禁飞线"}</div>
                  <div>来源: 自定义</div>
                  <div>类型: 线形</div>
                  <div>等级: ${zone.level || "无"}</div>
                </div>
              </div>
            `;
            polyline.bindPopup(popupContent);

            // 添加点击事件处理
            polyline.on("click", (evt) => {
              L.DomEvent.stop(evt);
              // 填充围栏表单数据
              fillFenceFormFromZone(zone);
            });
          }
        } catch (jsonError) {
          console.warn(
            "线形禁飞区JSON解析失败:",
            jsonError,
            "数据:",
            zone.polygon_points
          );
        }
      }
    } catch (error) {
      console.error("渲染自定义禁飞区失败:", error, "禁飞区数据:", zone);
    }
  });
}

// 从禁飞区数据填充围栏表单
function fillFenceFormFromZone(zone) {
  // 先重置围栏编辑状态
  resetFenceEditing();

  // 激活围栏工具
  activeTool.value = "fence";
  emit("tool-click", "fence");

  // 保存围栏ID（如果存在）
  if (zone.id) {
    fenceForm.id = zone.id;
  }

  // 根据禁飞区类型填充表单数据
  if (zone.zone_type === "polygon" && zone.polygon_points) {
    fenceForm.type = "polygon";
    fenceForm.name = zone.name || "";
    fenceForm.description = zone.description || "";
    fenceForm.altitude = zone.max_altitude || 120;
    fenceForm.active = zone.active !== false;

    try {
      let polygonPoints;
      // 检查polygon_points是否已经是对象/数组类型
      if (typeof zone.polygon_points === "object") {
        polygonPoints = zone.polygon_points;
      } else {
        // 尝试解析JSON字符串
        polygonPoints = JSON.parse(zone.polygon_points);
      }

      // 转换坐标格式并填充到表单
      if (Array.isArray(polygonPoints)) {
        fenceForm.points = polygonPoints.map((point, index) => ({
          id: index,
          name: `围栏点${index + 1}`,
          lat: point[1] || 0, // 后端是[lng, lat]，这里需要[lat, lng]
          lng: point[0] || 0,
        }));
      }
    } catch (e) {
      console.error("解析多边形坐标失败:", e);
    }
  } else if (zone.zone_type === "circle" && zone.radius) {
    fenceForm.type = "circle";
    fenceForm.name = zone.name || "";
    fenceForm.description = zone.description || "";
    fenceForm.altitude = zone.max_altitude || 120;
    fenceForm.active = zone.active !== false;
    fenceForm.centerLat = zone.lat || zone.center_latitude || "";
    fenceForm.centerLng = zone.lng || zone.center_longitude || "";
    fenceForm.radius = zone.radius || 200;
  } else if (zone.zone_type === "polyline" && zone.polygon_points) {
    fenceForm.type = "polygon"; // 目前表单只支持多边形和圆形，线形暂按多边形处理
    fenceForm.name = zone.name || "";
    fenceForm.description = zone.description || "";
    fenceForm.altitude = zone.max_altitude || 120;
    fenceForm.active = zone.active !== false;

    try {
      let polylinePoints;
      // 检查polygon_points是否已经是对象/数组类型
      if (typeof zone.polygon_points === "object") {
        polylinePoints = zone.polygon_points;
      } else {
        // 尝试解析JSON字符串
        polylinePoints = JSON.parse(zone.polygon_points);
      }

      // 转换坐标格式并填充到表单
      if (Array.isArray(polylinePoints)) {
        fenceForm.points = polylinePoints.map((point, index) => ({
          id: index,
          name: `围栏点${index + 1}`,
          lat: point[1] || 0, // 后端是[lng, lat]，这里需要[lat, lng]
          lng: point[0] || 0,
        }));
      }
    } catch (e) {
      console.error("解析线形坐标失败:", e);
    }
  }

  // 渲染围栏预览
  nextTick(() => {
    renderFencePreview();
  });
}

async function fetchAndRenderNoFlyZones() {
  const map = mapRef.value;
  if (!map) return;

  // 清空现有禁飞区图层，但要确保在获取新数据前清空，然后分别渲染两种围栏
  clearNoFlyLayer();
  console.log("开始获取并渲染禁飞区数据");

  const b = map.getBounds();
  const ltlat = b.getNorth();
  const ltlng = b.getWest();
  const rblat = b.getSouth();
  const rblng = b.getEast();
  try {
    if (noFlyAbort) noFlyAbort.abort();
    noFlyAbort = new AbortController();

    // 并行获取自定义禁飞区和DJI禁飞区
    const customZonesPromise = fetchCustomNoFlyZones();

    // 发送DJI API请求
    const djiPromise = noFlyZoneService.fetchDjiNoFlyZones({
      ltlat,
      ltlng,
      rblat,
      rblng,
      zonesMode: ZONE_MODE,
      droneType: DRONE_TYPE,
      zoneLevels: ZONE_LEVELS,
      signal: noFlyAbort.signal,
    });

    // 等待两个请求完成
    const [customZones, djiAreas] = await Promise.allSettled([
      customZonesPromise,
      djiPromise,
    ]);

    // 渲染自定义禁飞区
    if (customZones.status === "fulfilled") {
      renderCustomNoFlyZones(customZones.value);
    }

    // 渲染DJI禁飞区
    if (djiAreas.status === "fulfilled") {
      renderNoFlyAreas(djiAreas.value);
    }
  } catch (e) {
    // 可能遇到 CORS 或网络限制；可考虑后端代理
    console.warn("No-fly fetch failed", e);
  } finally {
    // 清除中止控制器引用
    setTimeout(() => {
      if (noFlyAbort) {
        noFlyAbort = null;
      }
    }, 1000);
  }
}

function renderNoFlyAreas(areas = []) {
  // 移除clearNoFlyLayer()调用，避免清除已渲染的自定义围栏
  // clearNoFlyLayer()  // 这个调用会清除自定义围栏
  const map = mapRef.value;
  if (!map || !noFlyLayer) return;
  areas.forEach((area) => {
    try {
      const area_rings = area?.sub_areas || [];
      if (area_rings.length > 0) {
        area_rings.map((area_item) => {
          const g = area_item;
          const style = zoneStyle(g.color);
          const rings = g.polygon_points || [];
          if (rings.length > 0) {
            rings.forEach((ring) => {
              const latlngs = ring.map((p) => [p[1], p[0]]);
              L.polygon(latlngs, style)
                .addTo(noFlyLayer)
                .bindPopup(popupHtml(area.name, g.level, g.height));
            });
          } else {
            const { lng, lat, radius, color, level, height } = area_item;
            const style = zoneStyle(color);
            L.circle([lat, lng], { radius, ...style })
              .addTo(noFlyLayer)
              .bindPopup(popupHtml(area.name, level, height));
          }
        });
      } else {
        const { lng, lat, radius, color, level, height, name } = area;
        const style = zoneStyle(color);
        L.circle([lat, lng], { radius, ...style })
          .addTo(noFlyLayer)
          .bindPopup(popupHtml(name, level, height));
      }
    } catch (e) {
      // 忽略无法解析的区域
    }
  });
}

// 刷新自定义禁飞区数据
async function refreshCustomNoFlyZones() {
  try {
    // 不再清空整个图层，而是分别重新渲染两种围栏
    // 这样可以确保自定义围栏和DJI围栏都能正确显示

    // 获取并渲染自定义禁飞区
    const customZones = await fetchCustomNoFlyZones();
    console.log(`刷新时获取到 ${customZones.length} 个自定义禁飞区`);
    renderCustomNoFlyZones(customZones);

    // 同时重新获取并渲染DJI禁飞区
    const map = mapRef.value;
    if (map) {
      const b = map.getBounds();
      const ltlat = b.getNorth();
      const ltlng = b.getWest();
      const rblat = b.getSouth();
      const rblng = b.getEast();
      if (noFlyAbort) noFlyAbort.abort();
      noFlyAbort = new AbortController();

      const areas = await noFlyZoneService.fetchDjiNoFlyZones({
        ltlat,
        ltlng,
        rblat,
        rblng,
        zonesMode: ZONE_MODE,
        droneType: DRONE_TYPE,
        zoneLevels: ZONE_LEVELS,
        signal: noFlyAbort.signal,
      });

      renderNoFlyAreas(areas);
    }

    // 显示成功消息
    if (typeof ElMessage !== "undefined") {
      ElMessage.success("禁飞区数据已刷新");
    }
  } catch (error) {
    console.error("刷新禁飞区失败:", error);
    // 显示错误消息
    if (typeof ElMessage !== "undefined") {
      ElMessage.error("刷新禁飞区失败");
    }
  }
}

// 刷新自定义禁飞区方法可在组件内部直接调用

function zoneStyle(color) {
  return { color, weight: 2, fillColor: color, fillOpacity: 0.22 };
}
function zoneLevel(level) {
  let heightStr = "";
  if (level < 3) {
    heightStr = "禁飞区";
  } else if (level < 5) {
    heightStr = "加强警示区";
  } else if (level < 7) {
    heightStr = "警示区";
  } else if (level < 9) {
    heightStr = "法规限制区";
  } else if (level == 10) {
    heightStr = "风景示范区";
  }
  return heightStr;
}

function popupHtml(name, level, height) {
  return `
    <div style="display: flex;align-items: center;gap: 6px;">
      <div>
        <div>区域名称: ${name}</div>
        <div>等级: ${zoneLevel(level)}</div>
        <div ${
          height > 0 ? "" : 'style="display:none"'
        }>高度限制: ${height} m</div>
      </div>
    </div>
  `;
}

// ====== 地址查询 ======
async function handleSearch() {
  // 获取当前地图范围
  const bounds = mapRef.value?.getBounds();
  const { _northEast, _southWest } = bounds;
  const { lat: ymax, lng: xmax } = _northEast;
  const { lat: ymin, lng: xmin } = _southWest;
  const mapBound = `${xmin},${ymin},${xmax},${ymax}`;

  // 构造请求参数
  const params = {
    keyWord: (searchKeyword.value || "").trim(),
    mapBound: mapBound,
    level: mapRef.value.getZoom(),
    queryType: 7, // 7表示地名搜索
    start: 0,
    count: 10,
  };

  searchError.value = "";
  searchResults.value = [];
  if (!params.keyWord) return;
  searchLoading.value = true;
  try {
    const data = await noFlyZoneService.searchLocations({
      params,
      token: TIANDITU_API_KEY,
    });
    searchResults.value = Array.isArray(data.pois) ? data.pois : [];
    if (!searchResults.value.length) searchError.value = "未找到匹配地址";
  } catch (e) {
    searchError.value = e?.message || "查询失败，请检查网络或更换关键词";
  } finally {
    searchLoading.value = false;
  }
}

function selectResult(item) {
  const map = mapRef.value;
  if (!map || !item) return;
  const latlng = item.lonlat.split(",").map(Number).reverse();
  try {
    if (searchMarker) map.removeLayer(searchMarker);
  } catch (e) {}
  searchMarker = L.marker(latlng, { title: item.name });
  searchMarker
    .addTo(map)
    .bindPopup(
      `<div><div>名称： ${item.name}</div><div>纬度：${latlng[0]}</div><div>经度：${latlng[1]}</div><div>地址：${item.address}</div></div>`
    )
    .openPopup();
  map.flyTo(latlng, Math.max(map.getZoom() || 14, 16));
  searchResults.value = [];
}

// 生命周期钩子
onMounted(() => {
  initMap();
});

defineExpose({ showTaskOnMap, resetActiveTool, externallyActivateTool });
</script>

<style lang="scss" scoped>
#app-page {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
.methane-monitor-overlay {
  position: absolute;
  top: 18px;
  left: 70px;
  z-index: 920;
}
.map-toolbar {
  position: absolute;
  top: 100px;
  left: 12px;
  z-index: 904;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 8px;
  background: rgba(17, 24, 39, 0.75);
  border-radius: 12px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
  backdrop-filter: blur(6px);
}

.map-toolbar .tool-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 35px;
  height: 35px;
  padding: 0px;
  border-radius: 6px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.08);
  color: #ffffff;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.map-toolbar .tool-btn .tool-icon i {
  font-size: 20px;
}

.map-toolbar .tool-btn .tool-label {
  font-size: 12px;
  letter-spacing: 0.5px;
}

.map-toolbar .tool-btn:hover {
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.15);
}

.map-toolbar .tool-btn.active {
  border-color: #2f88ff;
  background: rgba(47, 136, 255, 0.25);
  box-shadow: 0 0 12px rgba(47, 136, 255, 0.35);
}

.map-toolbar .tool-btn.secondary {
  background: rgba(255, 255, 255, 0.05);
  border: 1px dashed rgba(255, 255, 255, 0.35);
}

.map-toolbar .tool-btn.secondary:hover {
  border-color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.12);
}

.map-toolbar .tool-divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.16);
  margin: 4px 0;
}

@media (max-width: 1080px) {
  .map-toolbar {
    flex-direction: row;
    top: auto;
    bottom: 12px;
    left: 12px;
    right: 12px;
    justify-content: center;
  }

  .map-toolbar .tool-btn {
    flex-direction: row;
    width: auto;
    padding: 8px 12px;
  }

  .map-toolbar .tool-btn .tool-icon {
    font-size: 14px;
  }

  .map-toolbar .tool-btn .tool-label {
    font-size: 13px;
  }

  .map-toolbar .tool-divider {
    width: 1px;
    height: 24px;
    margin: 0 12px;
  }
}

.map-warp {
  width: 100%;
  height: 100%;
  font-size: 12px;
}

.leaflet-touch .leaflet-control-layers-toggle {
  width: 30px !important;
  height: 30px !important;
}
.leaflet-retina .leaflet-control-layers-toggle {
  background-size: 20px 20px;
}

/* 地址查询样式（仅测量页显示） */

/* Panel UI styles moved into RouteToolPanel.vue and FenceToolPanel.vue */

:deep(.route-waypoint-marker) {
  border: none;
  background: transparent;
  pointer-events: auto;
}

:deep(.route-waypoint-inner) {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, #ff7a45, #ff4d4f);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 14px rgba(255, 122, 69, 0.35);
  border: 2px solid #ffffff;
}

:deep(.route-waypoint-inner span) {
  color: #ffffff;
  font-size: 12px;
  font-weight: 700;
}

.map-search {
  position: absolute;
  top: 12px;
  left: 20px;
  z-index: 902;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
.map-search .search-input {
  width: 320px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  outline: none;
}
.map-search .search-input:focus {
  border-color: #2f88ff;
  box-shadow: 0 0 0 2px rgba(47, 136, 255, 0.15);
}
.map-search .search-btn {
  height: 32px;
  padding: 0 12px;
  border: 1px solid #2f88ff;
  background: #2f88ff;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
}
.map-search .search-btn[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}
.map-search .search-results {
  position: absolute;
  top: 40px;
  left: 0;
  width: 320px;
  max-height: 240px;
  overflow: auto;
  background: rgba(31, 41, 55, 0.6);
  border: 1px solid #e5e6eb;
  border-radius: 6px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
  padding: 6px 0;
}
.map-search .search-results li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  cursor: pointer;
}
.map-search .search-results li:hover {
  background: #f5f7ff;
}
.map-search .search-results .name {
  color: #1d2129;
}
.map-search .search-results .coord {
  color: #86909c;
}
.map-search .search-error {
  position: absolute;
  top: 40px;
  left: 0;
  background: #fff7e6;
  border: 1px solid #ffd591;
  color: #d48806;
  padding: 6px 10px;
  border-radius: 4px;
}

/* 航线选择面板样式 */
.route-selector-panel {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 360px;
  max-height: 60vh;
  background: rgba(17, 24, 39, 0.95);
  border-radius: 12px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.45);
  z-index: 950;
  display: flex;
  flex-direction: column;
  backdrop-filter: blur(10px);
}

.route-selector-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
}

.route-selector-header h3 {
  margin: 0;
  font-size: 18px;
  color: #f3f4f6;
}

.route-selector-close {
  border: none;
  background: transparent;
  color: #9ca3af;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}

.route-selector-close:hover {
  color: #e5e7eb;
}

.route-selector-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.route-selector-search {
  padding: 16px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.2);
}

.route-selector-search input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid rgba(148, 163, 184, 0.4);
  border-radius: 6px;
  background: rgba(17, 24, 39, 0.3);
  color: #f3f4f6;
  font-size: 14px;
}

.route-selector-search input:focus {
  outline: none;
  border-color: #2563eb;
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

.route-selector-list {
  flex: 1;
  overflow-y: auto;
}

.route-selector-item {
  padding: 10px 16px;
  cursor: pointer;
  transition: background-color 0.2s ease;
  border-bottom: 1px solid rgba(148, 163, 184, 0.1);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.route-selector-item:hover {
  background: rgba(37, 99, 235, 0.1);
}

.route-selector-item:last-child {
  border-bottom: none;
}

.selected {
  background: #0c63c4;
}
.route-selector-checkbox {
  color: #fff;
}

.route-name {
  display: block;
  font-size: 15px;
  font-weight: 500;
  color: #f3f4f6;
  margin-bottom: 4px;
}

.route-info {
  display: block;
  font-size: 12px;
  color: #9ca3af;
}

.waypoint-popup {
  font-size: 12px;
  line-height: 1.5;
}

.waypoint-popup strong {
  color: #2563eb;
}

/* 过渡动画 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

:deep(.task-drone-icon) {
  background: transparent;
  border: none;
}

:deep(.task-drone-icon .drone-icon-inner) {
  background: rgba(24, 144, 255, 0.95);
  white-space: nowrap;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 500;
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.35);
  padding: 2px 6px;
  border-radius: 2px;
  width: 50px;
  margin-top: -10px;
}

:deep(.leaflet-popup .drone-popup) {
  min-width: 180px;
}

:deep(.leaflet-popup .drone-popup .title) {
  font-weight: 600;
  color: #303133;
  margin-bottom: 4px;
}

:deep(.leaflet-popup .drone-popup div) {
  font-size: 12px;
  line-height: 18px;
}
</style>
